<!--
  Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.

  https://www.mall4j.com/

  未经允许，不可做商业用途！

  版权所有，侵权必究！
-->

<template>
  <div class="Mall4j component-mul-pic-upload">
    <el-upload
      ref="uploadRef"
      action=""
      :headers="{ Authorization: token }"
      list-type="picture-card"
      multiple
      :on-preview="handlePictureCardPreview"
      :on-remove="handleRemove"
      :http-request="handleFileChange"
      :on-change="handleAvatarChange"
      :class="{hide: hideUploadEdit}"
      :before-upload="beforeAvatarUpload"
      :file-list="fileList"
    >
      <el-icon class="icon-plus">
        <Plus />
      </el-icon>
    </el-upload>
    <el-dialog
      v-if="!isLogist"
      v-model="dialogVisible"
    >
      <img
        class="dialog-img"
        :src="checkFileUrl(dialogImageUrl)"
        alt
      >
    </el-dialog>
  </div>
</template>

<script setup>
import Cookie from 'vue-cookies'
import imageCompression from 'browser-image-compression'
import { ElMessage } from 'element-plus'
import { uploadFile } from '@/utils/http.js'

const props = defineProps({
  modelValue: {
    default: '',
    type: String
  },
  // 最大上传数量
  limit: {
    default: 3,
    type: Number
  },
  fileList: {
    default: () => [],
    type: Array
  },
  isLogist: {
    type: Boolean,
    default: false
  }
})
const emit = defineEmits(['input', 'imgPreview', 'update:modelValue'])

const token = computed(() => {
  return Cookie.get('bbcToken')
})

const hideUploadEdit = ref(false)
onMounted(() => {
  nextTick(() => {
    hideUploadEdit.value = props.fileList.length >= props.limit
  })
})

const uploadRef = ref(null)
/**
 * 图片预上传
 */
let uploadFiles = 0
// eslint-disable-next-line no-unused-vars
const handleAvatarChange = (response, file) => {
  uploadFiles = file.length
  if (uploadFiles >= props.limit) {
    hideUploadEdit.value = true
  }
}

// 限制图片上传大小
const beforeAvatarUpload = async (file) => {
  if (uploadFiles > props.limit) {
    return Promise().reject()
  }
  // 判断图片类型来筛选图片格式上传
  const _type = file.type
  if (_type.indexOf('png') === -1 && _type.indexOf('jpg') === -1 && _type.indexOf('jpeg') === -1) {
    ElMessage.error($t('imageNoformatUpload'))
    return Promise().reject()
  }
  const isLt10M = file.size / 1024 / 1024 < 10
  if (!isLt10M) {
    try {
      const resultBlob = await imageCompression(file, {
        maxSizeMB: 10 // 压缩大小
      })
      return new File([resultBlob], file.name, {
        type: file.type
      })
    } catch (error) {
      return Promise().reject()
    }
  }
}
let filePath = []
// eslint-disable-next-line no-unused-vars
const handleRemove = (file, fileList) => {
  const pics = filePath.filter(filePathItem => fileList.some(fileListItem => filePathItem.uid === fileListItem.uid))
  const filePaths = pics.map(item => item.filePath).join(',')
  filePath = pics
  emit('update:modelValue', filePaths)
  setTimeout(() => {
    hideUploadEdit.value = fileList.length >= props.limit
  }, 600)
}

const dialogImageUrl = ref('')
const dialogVisible = ref(false)
const handlePictureCardPreview = (file) => {
  if (props.isLogist) {
    emit('imgPreview', file.url)
  } else {
    dialogVisible.value = true
    dialogImageUrl.value = file.url
  }
}
let resData = []
const handleFileChange = (e) => {
  const file = e.file
  http({
    url: '/p/file/getPreSignUrl',
    method: 'get',
    params: {
      fileName: file.name,
      isImFile: false
    }
  }).then(async ({ data }) => {
    await uploadFile(data.preSignUrl, file).then(() => {
      filePath.push({ filePath: data.filePath, fileId: data.fileId, uid: file.uid })
      resData.push({ fileId: data.fileId, attachFileGroupId: 0, fileSize: file.size })
      if (uploadFiles === filePath.length) {
        http({
          url: '/p/file/uploadSuccess',
          method: 'put',
          data: resData
        }).then(() => {
          resData = []
          const pics = filePath.map(file => {
            return file.filePath
          }).join(',')
          emit('update:modelValue', pics)
        })
      }
      e.onSuccess()
    })
  })
}

</script>

<style lang="scss" scoped>
.component-mul-pic-upload {
  .dialog-img {
    display: block;
    object-fit: contain;
    margin: 0 auto;
    max-width: 100%;
  }
  .icon-plus {
    margin-top: 0 !important;
    &:deep(svg) {
      width: 20px;
      height: 20px;
    }
  }
  .hide :deep(.el-upload--picture-card){
  display: none;
}
}
</style>
